<?

error_reporting(E_ALL);

class Hddinfo {

	//Конфигурация по умолчанию

	var $os = 'linux'; //Операционная система, пока реализована поддержка только linux
	var $debug = false; //Включение/выключение дебаг режима, помогающего отловить ошибки.
	var $raid = false; //Включение поддержки рэйд массиово по умолчанию
	var $hddtemp = true; //Включает или выключает поддержку hddtemp;

	var $space_round = 2; //До какого знака округлять место на дисках
	var $byte = 1024; //Сколько байт в килобайте =)
	var $blue = 50; //Минимальный % для смены цвета полосы занятого места на синий
	var $red = 70; //Минимальный % для смены цвета полосы занятого места на красный
	var $critical_temp = 40; //Температура жёсткого диска которую нужно выделить цветом
	
	//Не используемые пока параметры
	
	var $notify_temp = 60; //Если температура достигнет этого порога, система пошлёт уведомление
	var $notify_space = 95; //Порог при котором будут посылатся уведомления о заполнении места на жёстком диске
	
	//Системные переменные их трогать не нужно
	
	var $creator_mail = '1@izhpt.com';
	var $total_space = 0;
	var $total_free_space = 0;
	var $total_used_space = 0;
	var $df = NULL;
	var $mdstat = NULL;
	
	private function switch_color($percent) {
	
		if($percent >= $this->red) return 'color_red';
		else if($percent >= $this->blue) return 'color_blue';
		else return 'color_green';
	
	}
	
	private function convert_size($size) {

		$stor_kb = round($size,$this->space_round);
		$stor_mb = round($size/$this->byte,$this->space_round);
		$stor_gb = round($size/$this->byte/$this->byte,$this->space_round);
		$stor_tb = round($size/$this->byte/$this->byte/$this->byte,$this->space_round);
		
		if( $stor_tb > 1 ) {
			$size = $stor_tb;
			$size .= ' Тб'; }
		else if( $stor_gb > 1 ) {
			$size = $stor_gb;
			$size .= ' Гб'; }
		else if( $stor_mb > 1) {
			$size = $stor_mb;
			$size .= ' Мб'; }
		else {
			$size = $stor_kb;
			$size .= ' Кб'; 
		}
		
		return $size;
	}

	private function request_info() {
	
		if($this->os == 'linux') {

			if(is_file('df.txt')) {
			
				$this->df = file_get_contents('df.txt');
				
			}
			
			if($this->raid) {

				if(is_file('mdstat.txt')) {
				
					$this->mdstat = file_get_contents('mdstat.txt');
				
				}
				else if(is_file('/proc/mdstat')) {
				
					$this->mdstat  = file_get_contents('/proc/mdstat');
				
				}
				else {
				
					$this->raid = false;
				
				}	
					
			
			}

			if($this->raid) {
				
					preg_match_all('/([0-9a-z]+) : active +(\w+) (.*?) +[0-9]+ +blocks.*? +\[[0-9]+\/[0-9]+\] +\[([U_]+)\]/ims',$this->mdstat,$md_parce);
					
					preg_match_all('/([0-9a-z]+) : active +.*?[0-9a-z]+ : active/ims',$this->mdstat,$md_recovery_);					
					
					$md_recovery_ = preg_split('/[0-9a-z]+ : active/ims',$this->mdstat);
					
					array_shift($md_recovery_);
					
					foreach($md_recovery_ as $key => $data) {
					
						preg_match_all('/\[[==>.]+\] +(recovery|resync) = ([0-9.]+)% \(([0-9]+)\/([0-9]+)\) +finish=([0-9.a-z]+) +speed=([0-9.a-z\/]+)/ims',$data,$md_recovery[$md_parce[1][$key]]);

						if($md_recovery[$md_parce[1][$key]][0] == NULL) {
							unset($md_recovery[$md_parce[1][$key]]);
						}
						else{
							unset($md_recovery[$md_parce[1][$key]][0]);
						}
					}
					
					if($md_recovery_ = '') {
					
						foreach($md_recovery as $key => $data) {
							
							$md_params["/dev/$key"]['r_type'] = $data[1][0];
							$md_params["/dev/$key"]['r_percent'] = $data[2][0];
							$md_params["/dev/$key"]['r_now'] = $this->convert_size($data[3][0]);
							$md_params["/dev/$key"]['r_total'] = $this->convert_size($data[4][0]);
							$md_params["/dev/$key"]['r_time'] = $data[5][0];
							$md_params["/dev/$key"]['r_speed'] = $data[6][0];
						
						}
						
						unset($md_recovery);
						
						foreach($md_parce[3] as $key => $devices) {
						
							preg_match_all('/([a-z]+\d+)/ims',$devices,$temp);
						
							foreach($temp[0] as $hdd) {
								
								$md_params['/dev/'.$md_parce[1][$key]]['type'] = strtoupper($md_parce[2][$key]);
								$md_params['/dev/'.$md_parce[1][$key]]['status'] = $md_parce[4][$key];
								$md_params['/dev/'.$md_parce[1][$key]]['dev']["/dev/$hdd"]['temp'] = exec("sudo hddtemp -n /dev/$hdd");							
							
							}									
						
						}
					
					}
					
					unset($md_parce);
			
			}
			
			isset($md_params) ? $this->raid = $md_params : $md_params = NULL;
		
			if (!isset($this->df)) $this->df  = `df -l | grep -o '^/dev/.*'`;
			
			$hdds = preg_split('/\n/', $this->df, -1, PREG_SPLIT_NO_EMPTY);
			
			foreach($hdds as $hdd) {
	
				$hdd_stat = preg_split('/ /', $hdd, -1, PREG_SPLIT_NO_EMPTY);
				
				$label = rtrim(substr($hdd_stat[0], 0, strlen($hdd_stat[0])-1));
				
				if($this->hddtemp) $temp = exec("sudo hddtemp -n $label");

				if (!$this->hddtemp or !is_numeric($temp)) $temp = NULL;
				
				if (isset($this->raid) and isset($this->raid[$hdd_stat[0]])) {
				
					$this->total_space = $this->total_space + $hdd_stat[1];
					$this->total_free_space = $this->total_free_space + $hdd_stat[3];
					$this->total_used_space = $this->total_used_space + $hdd_stat[2];
					
					$hdd_info['raid'][$hdd_stat[0]] = array(
					
						'total' => $this->convert_size($hdd_stat[1]),
						'used' => $this->convert_size($hdd_stat[2]),
						'free' => $this->convert_size($hdd_stat[3]),
						'percent' => rtrim(substr($hdd_stat[4], 0, strlen($hdd_stat[4])-1)),
						'mount' => $hdd_stat[5],
					
					);
					
					$hdd_info['raid'][$hdd_stat[0]] = array_merge($hdd_info['raid'][$hdd_stat[0]],$this->raid[$hdd_stat[0]]);				
				
				}
				else {
		
					$hdd_info[$label]['temp'] = $temp;

					$this->total_space = $this->total_space + $hdd_stat[1];
					$this->total_free_space = $this->total_free_space + $hdd_stat[3];
					$this->total_used_space = $this->total_used_space + $hdd_stat[2];
					
					$hdd_info[$label][$hdd_stat[0]] = array(
					
						'total' => $this->convert_size($hdd_stat[1]),
						'used' => $this->convert_size($hdd_stat[2]),
						'free' => $this->convert_size($hdd_stat[3]),
						'percent' => rtrim(substr($hdd_stat[4], 0, strlen($hdd_stat[4])-1)),
						'mount' => $hdd_stat[5]
					
					);
				
				}
			
			}
			
			$this->hdd = $hdd_info;
			
			
		}
		else {
		
		
		}
	
	}
	
	public function create_page() {
	
		header('Content-Type: text/html; charset=UTF-8'); //Шлём кодировку, ну так... для уверенности.
	
		$this->request_info();
	
		$header = '
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Hddinfo</title>
<link href="css/style.css" rel="stylesheet" type="text/css" />
</head>

<body>

<ul class="global_list">		
		';
		
		$footer = "
</ul>
<!-- &#8212; de-monstr ($this->creator_mail), 2009 .-->
</body>
</html>		
		";

		$tpl = NULL;

		if(isset($this->hdd['raid'])) {
		
			foreach($this->hdd['raid'] as $raid_dev => $data) {
			
				$tpl .= '<li>
    <table>
      <tr>
        <td class="image">
            <img src="images/raid_top.png" alt="" /><br/>';
			
				$count = count($data['dev']) - 2;
				
				while ($count >= 1) {
						
						$count = $count - 1;
						
						$tpl .= '<img src="images/raid_middle.png" alt="" /><br/>';
						
				}
			
				$tpl .= '
            <img src="images/raid_bottom.png" alt="" />        
        </td>
        <td class="info">';
			
				$tpl .= "<ul class=\"none highlight\">

            	<li><h1>$raid_dev $data[type]</h1></li>
                <li>";
				
				$color = $this->switch_color($data['percent']);

				$tpl .= "<a title=\"Смонтировано в $data[mount] Статус: [$data[status]]\">$raid_dev</a> 
                    <span class=\"p_bar\"><span class=\"$color\" style=\"width:$data[percent]%;\"><div>$data[percent]%</div></span>
                    </span>Свободно <b> $data[free]</b> из $data[total].
                </li>
                <li>
                	<ul>";
					
				if(isset($data['r_total'])) {
					$percent = round($data['r_percent'],0);
				}
				

				
				if(isset($data['r_type']) and $data['r_type'] == 'recovery') {
				
					$tpl .= "<li>Идёт восстановление <span class=\"p_bar\"><span class=\"color_heal\" style=\"width:$percent%;\"></span>
						</span> <a title=\"$data[r_time], $data[r_speed]. Восстановлено $data[r_now] из $data[r_total]\"><b>$data[r_percent]%</b></a></li>";
				
				}	
				else if(isset($data['r_type']) and $data['r_type'] == 'resync') {
				
					$tpl .= "<li>Идёт синхронизация <span class=\"p_bar\"><span class=\"color_resync\" style=\"width:$percent%;\"></span>
						</span> <a title=\"$data[r_time], $data[r_speed]. Синхронизировано $data[r_now] из $data[r_total]\"><b>$data[r_percent]%</b></a></li>";
				
				}	

					
				foreach($data['dev'] as $name => $comp_data) {
					
					$recovery = NULL;
					$recovery_ = NULL;
					
					$temp = NULL;
					
					if(isset($comp_data['temp']) and $comp_data['temp'] != '') {
					
						if($comp_data['temp'] >= $this->critical_temp) $temp = "| <b>$comp_data[temp]&deg;</b>";
						else $temp = "| $comp_data[temp]&deg;";
					
					}
				
					$tpl .= "<li>
                            $name $temp
                        </li>";
				
				}
				
				$tpl .= '
                    </ul>
                </li>    
            </ul></td>
      </tr>
    </table></li>';
			
			}
			
			unset($this->hdd['raid']);
		
		}
		
		if($this->hdd != '') {
		
			foreach($this->hdd as $hdd_dev => $data) {
			
				$tpl .= '    <table>
      <tr>
        <td class="image">
            <img src="images/hdd.png" alt="" />     
        </td>
        <td class="top">';


				if(isset($data['temp']) and $data['temp'] != '') {
	
					if($data['temp'] >= $this->critical_temp) $temp = "<b>$data[temp]&deg;</b>";
					else $temp = "$data[temp]&deg;";
				
				}
				else $temp = NULL;

				$tpl .= "<ul class=\"none\">

            	<li><h1>$hdd_dev $temp</h1></li>
                <li>";
				
				unset($data['temp']);
				
				foreach($data as $name => $params) {

					$color = $this->switch_color($params['percent']);

					$tpl .= "<a title=\"Смонтировано в $params[mount]\">$name</a> 
						<span class=\"p_bar\"><span class=\"$color\" style=\"width:$params[percent]%;\"><div>$params[percent]%</div></span>
						</span>Свободно <b> $params[free]</b> из $params[total].
					</li>
					<li>";
					
				}
				
				$tpl .= '
                </li>    
            </ul></td>
      </tr>
    </table></li>';
		
			}
		}
		
			$total_space = $this->convert_size($this->total_space);
			$total_free_space = $this->convert_size($this->total_free_space);
			$total_used_space = $this->convert_size($this->total_used_space);
	
			if($this->debug) {
			
				$tpl .= "<div class=\"warning\"><h2>Скрипт включен в режиме отладки</h2>
Если вы, не дай бог, найдёте ошибку, &#8212; вы можете отправить <a href=\"mailto:$this->creator_mail\">$this->creator_mail</a> содержимое каталога <b>debug</b>, расположенного в каталоге со скриптом. Пожалуйста, снабдите письмо <b>подробным описанием</b> условий выполнения скрипта, приводящих к ошибке, так как отладочная информация может не иметь всех необходимых сведений. Спасибо.</div></li>";
			
			}
	
			$total_stat = "
		<table>
		  <tr>
			<td class=\"image\">
				<img src=\"images/comp.png\" alt=\"\" />     
			</td>
			<td  class=\"middle\">
				<ul class=\"none\">
	
					<li><h1>Полный объём: <strong>$total_space</strong></h1></li>
					<li><h1>Использовано: <strong>$total_used_space</strong></h1></li>
					<li><h1>Свободно: <strong>$total_free_space</strong></h1></li>
					
				</ul>        
			</td>
		  </tr>
		</table>		
			";
		
		$this->page = $header.$tpl.$total_stat.$footer;
		
		if($this->debug) {
		
			$this->pack_debug_info();
		
		}
		
		echo $this->page;
	
	}
	
	private function pack_debug_info() {
	
		if(!is_dir('debug')) { mkdir('debug',0700); }
		
		if(isset($this->df)) file_put_contents('debug/df.txt',$this->df);
		
		if(isset($this->mdstat)) file_put_contents('debug/mdstat.txt',$this->mdstat);
		
		if(isset($this->page)) file_put_contents('debug/page.html',$this->page);
		
		file_put_contents('debug/class_dump.txt',print_r($this,true));
	
	}

}	

$hdd_info = new Hddinfo();

/*

	Включаем поддержку рэйдов, это не смертельно, выдумывать рейды система не будет, 
	но нагрузку снизить можно.

*/
$hdd_info->raid = true; 

/*

	Скрипт создаст папочку debug, в которую будет складывать результаты выполнения системных команд, 
	если был замечен сбой то всё содержимое debug пакуется и отправляется разработчику.

*/
$hdd_info->debug = true; 

$hdd_info->create_page();



?>